package cn.zwk.product.service.impl;

import cn.zwk.common.constant.ProductConstant;
import cn.zwk.product.entity.AttrAttrgroupRelationEntity;
import cn.zwk.product.entity.AttrGroupEntity;
import cn.zwk.product.entity.CategoryEntity;
import cn.zwk.product.service.AttrAttrgroupRelationService;
import cn.zwk.product.service.AttrGroupService;
import cn.zwk.product.service.CategoryService;
import cn.zwk.product.vo.AttrResVo;
import cn.zwk.product.vo.AttrVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.zwk.common.utils.PageUtils;
import cn.zwk.common.utils.Query;

import cn.zwk.product.dao.AttrDao;
import cn.zwk.product.entity.AttrEntity;
import cn.zwk.product.service.AttrService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;


@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private AttrGroupService groupService;

    @Autowired
    private AttrAttrgroupRelationService relationService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                new QueryWrapper<AttrEntity>()
        );

        return new PageUtils(page);
    }

    public PageUtils queryAttrPage(Map<String, Object> params, Long catelogId, ProductConstant.AttrEnum attrType) {
        IPage<AttrEntity> page = new Query<AttrEntity>().getPage(params);
        LambdaQueryWrapper<AttrEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.and(w -> {
            w.eq(AttrEntity::getAttrType, ProductConstant.AttrEnum.ATTR_TYPE_ALL.getCode()).or();
            switch (attrType) {
                case ATTR_TYPE_BASE:
                    w.eq(AttrEntity::getAttrType, ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode());
                    break;
                case ATTR_TYPE_SALE:
                    w.eq(AttrEntity::getAttrType, ProductConstant.AttrEnum.ATTR_TYPE_SALE.getCode());
                    break;
            }
        });
        if (catelogId != 0) {
            wrapper.eq(AttrEntity::getCatelogId, catelogId);
        }
        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key)) {
            wrapper.and((w) -> {
                w.eq(AttrEntity::getAttrId, key).or().like(AttrEntity::getAttrName, key);
            });
        }
        //构造完条件
        IPage<AttrEntity> resultPage = this.page(page, wrapper);
        List<AttrResVo> result = resultPage.getRecords().stream().map(attr -> {
            AttrResVo vo = new AttrResVo();
            BeanUtils.copyProperties(attr, vo);
            AttrAttrgroupRelationEntity relation = relationService.getOne(
                    new LambdaQueryWrapper<AttrAttrgroupRelationEntity>().eq(AttrAttrgroupRelationEntity::getAttrId, attr.getAttrId())
            );
            if (relation != null) {
                Long groupId = relation.getAttrGroupId();
                AttrGroupEntity groupEntity = groupService.getById(groupId);
                if (groupEntity != null) {
                    vo.setGroupName(groupEntity.getAttrGroupName());
                }
            }
            CategoryEntity categoryEntity = categoryService.getById(attr.getCatelogId());
            if (categoryEntity != null) {
                String categoryName = categoryEntity.getName();
                vo.setCatelogName(categoryName);
            }
            return vo;
        }).collect(Collectors.toList());
        return new PageUtils(resultPage, result);
    }

    @Override
    public PageUtils queryBaseAttrPage(Map<String, Object> params, Long catelogId) {
        return this.queryAttrPage(params, catelogId, ProductConstant.AttrEnum.ATTR_TYPE_BASE);
    }

    @Override
    public PageUtils querySaleAttrPage(Map<String, Object> params, Long catelogId) {
        return this.queryAttrPage(params, catelogId, ProductConstant.AttrEnum.ATTR_TYPE_SALE);
    }

    @Override
    public AttrResVo getAttrInfo(Long attrId) {
        AttrResVo resVo = new AttrResVo();
        AttrEntity attrEntity = this.getById(attrId);
        if (attrEntity == null) {
            return null;
        }
        BeanUtils.copyProperties(attrEntity, resVo);
        AttrAttrgroupRelationEntity relation = relationService.getOne(
                new LambdaUpdateWrapper<AttrAttrgroupRelationEntity>().eq(AttrAttrgroupRelationEntity::getAttrId, attrId)
        );
        if (relation != null) {
            resVo.setAttrGroupId(relation.getAttrGroupId());
        }
        List<CategoryEntity> catelogPath = categoryService.findCatelogPath(resVo.getCatelogId());
        List<Long> collect = catelogPath.stream().map(category -> category.getCatId()).collect(Collectors.toList());
        resVo.setCatelogPath(collect.toArray(new Long[]{}));
        return resVo;
    }

    @Override
    @Transactional
    public void saveAttr(AttrVo attrVo) {
        this.save(attrVo);
        //保存关联关系
        AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
        relationEntity.setAttrId(attrVo.getAttrId());
        relationEntity.setAttrGroupId(attrVo.getAttrGroupId());
        relationService.save(relationEntity);
    }

    @Override
    @Transactional
    public void updateAttr(AttrVo attrVo) {
        this.updateById(attrVo);
        //修改关联关系
        AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
        relationEntity.setAttrId(attrVo.getAttrId());
        relationEntity.setAttrGroupId(attrVo.getAttrGroupId());
        relationService.saveOrUpdate(relationEntity, new LambdaUpdateWrapper<AttrAttrgroupRelationEntity>().eq(AttrAttrgroupRelationEntity::getAttrId, attrVo.getAttrId()));
    }
}
